/*
 * Created on Mar 10, 2005
 * Created by dfhuynh
 */
package edu.mit.simile.longwell.query.project;

import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource;

import edu.mit.simile.longwell.Profile;
import edu.mit.simile.longwell.tag.ITagModel;

/**
 * @author dfhuynh
 */
public class TagProjector extends ProjectorBase {
	final protected ITagModel m_tagModel;
	final protected String m_locale;
	
	/**
	 * @param profile
	 */
	public TagProjector(Profile profile, String parameter, String locale) {
		super(profile);
		m_tagModel = (ITagModel) profile.getStructuredModel(ITagModel.class);
		m_locale = locale;
	}
	
	protected class TagProjection extends ProjectionBase {
		final protected Set m_objects;
		
		TagProjection(Set objects, String locale) {
			super(locale);
			m_objects = objects;
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.ProjectionBase#getObjects(java.lang.Object)
		 */
		public Set getObjects(Object value) {
			return super.getObjects(
				value == null ? 
					null :
					(value instanceof String ? 
						value : 
						((Literal) value).getString()));
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.ProjectionBase#getValues()
		 */
		public Set getValues() {
			return m_tagModel.getTagLabels();
		}

		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.ProjectionBase#internalGetValue(com.hp.hpl.jena.rdf.model.Resource)
		 */
		protected Object internalGetValue(Resource object) {
			Set tagLabels = m_tagModel.getObjectTagLabels(object);
			return tagLabels.size() > 0 ? tagLabels.iterator().next() : null;
		}

		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.ProjectionBase#internalGetObjects(java.lang.Object)
		 */
		protected Set internalGetObjects(Object value) {
			Set objects = m_tagModel.getObjects((String) value);
			
			if (m_objects != null) {
				objects = new HashSet(objects);
				objects.retainAll(m_objects);
			}
			
			return objects;
		}

		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.ProjectionBase#internalGetObjectToValueMap()
		 */
		protected Map internalGetObjectToValueMap() {
			// TODO What do we do here?
			return null;
		}

		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.IProjection#getObjects()
		 */
		public Set getObjects() {
			return m_objects != null ? m_objects : 
				m_profile.getSchemaModel().getAllObjects();
		}

		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.IProjection#getUniqueness()
		 */
		public float getUniqueness() {
			return 0;
		}

		@Override
		public String getProperty() {
			// TODO Auto-generated method stub
			return null;
		}
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.ProjectorBase#internalProject()
	 */
	protected IProjection internalProject() {
		return new TagProjection(null, m_locale);
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.ProjectorBase#internalProject(java.util.Set)
	 */
	protected IProjection internalProject(Set objects) {
		return new TagProjection(objects, m_locale);
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.IProjector#isEfficientForRootProjection()
	 */
	public boolean isEfficientForRootProjection() {
		return false;
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.IProjector#getUniqueness()
	 */
	public float getUniqueness() {
		return 0;
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.IProjector#getParameter()
	 */
	public String getParameter() {
		return "";
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.IProjector#getLabel(java.lang.String)
	 */
	public String getLabel(String locale) {
		ResourceBundle resources = ResourceBundle.getBundle(
			this.getClass().getName(),
			locale == null ? 
				Locale.getDefault() : new Locale(locale));

		return resources.getString("Label");
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.ProjectorBase#onAfterChange(com.hp.hpl.jena.rdf.model.Model)
	 */
	protected void onAfterChange(Model model) {
		super.onAfterChange(model);
		if (model.listObjectsOfProperty(
				model.createProperty(ITagModel.s_simile_tag)).hasNext()) {
			m_resultCache.clear();
			s_rootProjections.remove(this);
		}
	}
}
